import os
from datetime import datetime
from tkinter import filedialog, messagebox
import os
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
import pandas as pd
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4, landscape
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.units import inch
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
from utils.log_handler import logger

# ---------------------- Windows 通用配置 ----------------------
# 中文字体路径（Windows 系统默认黑体，备选微软雅黑）
FONT_PATH = "C:/Windows/Fonts/simhei.ttf"
FONT_NAME = "SimHei"
if not os.path.exists(FONT_PATH):
    FONT_PATH = "C:/Windows/Fonts/msyh.ttc"  # 适配部分Windows版本的微软雅黑
    FONT_NAME = "Microsoft YaHei"

# 默认导出路径（Windows 文档目录，自动创建）
DEFAULT_EXPORT_PATH = os.path.join(os.path.expanduser("~"), "Documents", "GanttExports")
DEFAULT_EXPORT_PATH = DEFAULT_EXPORT_PATH.replace("/", "\\")  # 转换为Windows路径分隔符
os.makedirs(DEFAULT_EXPORT_PATH, exist_ok=True)


# ---------------------- Excel 导出（任务详情表） ----------------------
def export_tasks_to_excel(tasks, project_id):
    """Windows 环境Excel导出：含样式美化、中文适配、特殊字符处理"""
    try:
        # 1. 获取项目名称（用于文件名和标题）
        from data_manager.db_handler import get_project_by_id
        project = get_project_by_id(int(project_id))
        project_name = project[1] if project else "未命名项目"

        # 2. 生成合法文件名（过滤Windows不允许的特殊字符）
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        invalid_chars = ['\\', '/', ':', '*', '?', '"', '<', '>', '|']
        safe_project_name = project_name
        for char in invalid_chars:
            safe_project_name = safe_project_name.replace(char, "_")
        default_filename = f"项目任务表_{safe_project_name}_{timestamp}.xlsx"

        # 3. 选择保存路径（初始目录为默认导出路径）
        save_path = filedialog.asksaveasfilename(
            initialdir=DEFAULT_EXPORT_PATH,
            initialfile=default_filename,
            defaultextension=".xlsx",
            filetypes=[("Excel 文件 (*.xlsx)", "*.xlsx"), ("所有文件 (*.*)", "*.*")]
        )
        if not save_path:
            logger.info("Excel导出取消：用户未选择保存路径")
            return

        # 4. 准备任务数据（适配task_panel的返回格式）
        task_columns = [
            "任务ID", "任务名称", "优先级", "负责人", "开始日期",
            "计划结束日期", "任务状态", "完成进度(%)", "任务描述", "依赖任务"
        ]
        task_data = [
            [
                task[0], task[1], task[2], task[3], task[4],
                task[5], task[6], task[7], task[8], task[9]
            ] for task in tasks
        ]
        df = pd.DataFrame(task_data, columns=task_columns)

        # 5. 创建Excel工作簿并设置样式
        wb = openpyxl.Workbook()
        ws = wb.active
        ws.title = "任务详情"

        # 5.1 写入标题（合并单元格+蓝色主题样式）
        title = f"{project_name} - 任务清单（导出时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}）"
        ws.merge_cells(f"A1:J1")
        ws["A1"] = title
        # 标题样式配置
        title_font = Font(name=FONT_NAME, size=14, bold=True, color="FFFFFF")
        title_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
        title_alignment = Alignment(horizontal="center", vertical="center")
        ws["A1"].font = title_font
        ws["A1"].fill = title_fill
        ws["A1"].alignment = title_alignment
        ws.row_dimensions[1].height = 30  # 调整标题行高度

        # 5.2 写入列名（灰色背景+加粗）
        for col_idx, col_name in enumerate(task_columns, 1):
            cell = ws.cell(row=2, column=col_idx, value=col_name)
            cell.font = Font(name=FONT_NAME, size=11, bold=True)
            cell.fill = PatternFill(start_color="E7E6E6", end_color="E7E6E6", fill_type="solid")
            cell.alignment = Alignment(horizontal="center", vertical="center")

        # 5.3 写入任务数据（按状态着色）
        for row_idx, (_, row) in enumerate(df.iterrows(), 3):
            for col_idx, value in enumerate(row, 1):
                cell = ws.cell(row=row_idx, column=col_idx, value=value)
                cell.font = Font(name=FONT_NAME, size=10)
                cell.alignment = Alignment(horizontal="center", vertical="center")
                # 按任务状态设置背景色（提升可读性）
                if col_idx == 7:  # 第7列为"任务状态"
                    status_color_map = {
                        "未开始": "E7E6E6",
                        "进行中": "D5E8D4",
                        "已完成": "C6E0B4",
                        "延期": "F8CBAD"
                    }
                    cell.fill = PatternFill(
                        start_color=status_color_map.get(value, "FFFFFF"),
                        end_color=status_color_map.get(value, "FFFFFF"),
                        fill_type="solid"
                    )

        # 5.4 设置边框和列宽（适配内容长度）
        thin_border = Border(
            left=Side(style="thin"), right=Side(style="thin"),
            top=Side(style="thin"), bottom=Side(style="thin")
        )
        # 为所有数据单元格添加边框
        for row in ws.iter_rows(min_row=2, max_row=len(df)+2, min_col=1, max_col=len(task_columns)):
            for cell in row:
                cell.border = thin_border
        # 手动设置列宽（避免内容溢出）
        column_widths = [8, 25, 8, 12, 12, 12, 10, 12, 30, 20]
        for col_idx, width in enumerate(column_widths, 1):
            col_letter = openpyxl.utils.get_column_letter(col_idx)
            ws.column_dimensions[col_letter].width = width

        # 6. 保存Excel文件（处理Windows权限问题）
        wb.save(save_path)
        logger.info(f"Excel导出成功（Windows）：{save_path}")
        messagebox.showinfo("导出成功", f"任务表已导出至：\n{save_path}", parent=None)

    except Exception as e:
        logger.error(f"Excel导出失败（Windows）：{str(e)}")
        messagebox.showerror("导出失败", f"Excel导出出错：{str(e)}", parent=None)


# ---------------------- PDF 导出（图表/完整报告） ----------------------
def export_figure_to_pdf(figure, filename):
    """Windows 环境PDF图表导出（支持matplotlib生成的甘特图/统计图表）"""
    try:
        # 1. 处理文件名（过滤Windows特殊字符）
        invalid_chars = ['\\', '/', ':', '*', '?', '"', '<', '>', '|']
        safe_filename = filename
        for char in invalid_chars:
            safe_filename = safe_filename.replace(char, "_")

        # 2. 选择保存路径
        save_path = filedialog.asksaveasfilename(
            initialdir=DEFAULT_EXPORT_PATH,
            initialfile=safe_filename,
            defaultextension=".pdf",
            filetypes=[("PDF 文件 (*.pdf)", "*.pdf"), ("所有文件 (*.*)", "*.*")]
        )
        if not save_path:
            logger.info("PDF图表导出取消：用户未选择保存路径")
            return False

        # 3. 保存图表为PDF（横向A4格式，适配Windows打印）
        with PdfPages(save_path) as pdf:
            figure.set_size_inches(landscape(A4)[0]/inch, landscape(A4)[1]/inch)
            pdf.savefig(figure, bbox_inches="tight")
            plt.close(figure)  # 关闭图表释放内存

        logger.info(f"PDF图表导出成功（Windows）：{save_path}")
        messagebox.showinfo("导出成功", f"图表已导出至：\n{save_path}", parent=None)
        return True

    except Exception as e:
        logger.error(f"PDF图表导出失败（Windows）：{str(e)}")
        messagebox.showerror("导出失败", f"PDF图表导出出错：{str(e)}", parent=None)
        return False


def export_project_report(project_id, gantt_fig, stat_pie_fig, stat_line_fig):
    """Windows 环境项目完整报告PDF导出：含项目信息、统计图表、甘特图"""
    try:
        # 1. 获取项目基础信息和任务数据
        from data_manager.db_handler import get_project_by_id, get_tasks_by_project
        project = get_project_by_id(int(project_id))
        if not project:
            messagebox.showwarning("导出失败", "未找到项目信息，请确认项目ID有效", parent=None)
            return
        project_id, project_name, start_date, end_date, description = project
        tasks = get_tasks_by_project(int(project_id))

        # 2. 生成合法报告文件名
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        invalid_chars = ['\\', '/', ':', '*', '?', '"', '<', '>', '|']
        safe_project_name = project_name
        for char in invalid_chars:
            safe_project_name = safe_project_name.replace(char, "_")
        default_filename = f"项目报告_{safe_project_name}_{timestamp}.pdf"

        # 3. 选择保存路径
        save_path = filedialog.asksaveasfilename(
            initialdir=DEFAULT_EXPORT_PATH,
            initialfile=default_filename,
            defaultextension=".pdf",
            filetypes=[("PDF 文件 (*.pdf)", "*.pdf"), ("所有文件 (*.*)", "*.*")]
        )
        if not save_path:
            logger.info("项目报告导出取消：用户未选择保存路径")
            return

        # 4. 初始化PDF文档（横向A4，适配Windows阅读）
        doc = SimpleDocTemplate(save_path, pagesize=landscape(A4))
        elements = []
        styles = getSampleStyleSheet()

        # 5. 注册Windows中文字体（避免PDF中文乱码）
        try:
            pdfmetrics.registerFont(TTFont(FONT_NAME, FONT_PATH))
            # 自定义PDF文本样式（标题、章节标题、正文）
            title_style = ParagraphStyle(
                "CustomTitle",
                parent=styles["Heading1"],
                fontName=FONT_NAME,
                fontSize=20,
                spaceAfter=30,
                alignment=1  # 居中对齐
            )
            heading_style = ParagraphStyle(
                "CustomHeading",
                parent=styles["Heading2"],
                fontName=FONT_NAME,
                fontSize=16,
                spaceAfter=20,
                textColor=colors.HexColor("#4472C4")  # 蓝色章节标题
            )
            normal_style = ParagraphStyle(
                "CustomNormal",
                parent=styles["Normal"],
                fontName=FONT_NAME,
                fontSize=11,
                spaceAfter=10
            )
        except Exception as e:
            logger.warning(f"PDF中文字体注册失败（Windows）：{str(e)}，将使用默认字体")
            title_style = styles["Heading1"]
            heading_style = styles["Heading2"]
            normal_style = styles["Normal"]

        # 6. 构建PDF报告内容（分章节）
        # 6.1 报告标题
        title = Paragraph(f"项目甘特图报告 - {project_name}", title_style)
        elements.append(title)

        # 6.2 项目基本信息（表格展示）
        elements.append(Paragraph("一、项目基本信息", heading_style))
        project_data = [
            ["项目名称", project_name],
            ["项目ID", str(project_id)],
            ["开始日期", start_date],
            ["计划结束日期", end_date],
            ["项目描述", description if description else "无"]
        ]
        project_table = Table(project_data, colWidths=[1.5*inch, 6*inch])
        project_table.setStyle(TableStyle([
            ("FONTNAME", (0, 0), (-1, -1), FONT_NAME),
            ("FONTSIZE", (0, 0), (-1, -1), 11),
            ("GRID", (0, 0), (-1, -1), 1, colors.black),
            ("BACKGROUND", (0, 0), (0, -1), colors.HexColor("#E7E6E6")),  # 左列灰色背景
            ("ALIGN", (0, 0), (0, -1), "CENTER"),  # 左列居中
            ("VALIGN", (0, 0), (-1, -1), "MIDDLE")  # 垂直居中
        ]))
        elements.append(project_table)
        elements.append(Spacer(1, 20))  # 插入空白间隔

        # 6.3 任务统计概览（文字+饼图）
        elements.append(Paragraph("二、任务统计概览", heading_style))
        total_tasks = len(tasks)
        status_count = {}
        for task in tasks:
            status = task[6]
            status_count[status] = status_count.get(status, 0) + 1
        # 统计文字描述
        stat_text = f"当前项目共包含 {total_tasks} 个任务，各状态分布如下：<br/>"
        for status, count in status_count.items():
            rate = (count / total_tasks) * 100 if total_tasks > 0 else 0
            stat_text += f"- {status}：{count} 个（{rate:.1f}%）<br/>"
        elements.append(Paragraph(stat_text, normal_style))
        elements.append(Spacer(1, 10))

        # 插入任务状态饼图（临时图片）
        temp_pie_path = os.path.join(DEFAULT_EXPORT_PATH, "temp_task_status_pie.png")
        stat_pie_fig.savefig(temp_pie_path, dpi=150, bbox_inches="tight")
        from reportlab.platypus import Image
        pie_image = Image(temp_pie_path, width=3*inch, height=3*inch)
        elements.append(pie_image)
        elements.append(Spacer(1, 20))

        # 插入进度趋势线图（临时图片）
        temp_line_path = os.path.join(DEFAULT_EXPORT_PATH, "temp_progress_trend.png")
        stat_line_fig.savefig(temp_line_path, dpi=150, bbox_inches="tight")
        line_image = Image(temp_line_path, width=6*inch, height=3*inch)
        elements.append(line_image)
        elements.append(Spacer(1, 30))

        # 6.4 项目甘特图
        elements.append(Paragraph("三、项目甘特图", heading_style))
        temp_gantt_path = os.path.join(DEFAULT_EXPORT_PATH, "temp_project_gantt.png")
        gantt_fig.savefig(temp_gantt_path, dpi=150, bbox_inches="tight")
        gantt_image = Image(temp_gantt_path, width=8*inch, height=5*inch)
        elements.append(gantt_image)
        elements.append(Spacer(1, 30))

        # 6.5 报告说明
        elements.append(Paragraph("四、报告说明", heading_style))
        note_text = f"""
        1. 本报告生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}<br/>
        2. 甘特图颜色含义：高优先级（红色）、中优先级（黄色）、低优先级（绿色）、已完成（灰色）、延期（深红色）<br/>
        3. 进度趋势图按任务计划结束日期分组，展示每日任务平均完成进度<br/>
        4. 建议定期导出报告，用于项目进度跟踪、团队同步和归档备份
        """
        elements.append(Paragraph(note_text, normal_style))

        # 7. 生成PDF并清理临时文件
        doc.build(elements)
        # 删除临时图片（处理Windows文件占用问题）
        temp_files = [temp_pie_path, temp_line_path, temp_gantt_path]
        for temp_file in temp_files:
            if os.path.exists(temp_file):
                try:
                    os.remove(temp_file)
                except PermissionError:
                    logger.warning(f"临时文件删除失败（权限占用）：{temp_file}，可手动删除")
                except Exception as e:
                    logger.error(f"删除临时文件出错：{str(e)}，路径：{temp_file}")

        logger.info(f"项目报告PDF导出成功（Windows）：{save_path}")
        messagebox.showinfo("导出成功", f"项目报告已导出至：\n{save_path}", parent=None)

    except Exception as e:
        logger.error(f"项目报告PDF导出失败（Windows）：{str(e)}")
        messagebox.showerror("导出失败", f"项目报告PDF导出出错：{str(e)}", parent=None)
